﻿using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Text.RegularExpressions;
using Streaming_Service.Enum;
using Streaming_Service.Media;
using Streaming_Service.SQL_Ting;

namespace Streaming_Service.Crawler {
    public class ImdbCrawler {
        public static string ImdbMovieUrl = "http://www.imdb.com/title/{ID}/";

        public static ImdbMovieEntry GetMovieInfo(string imdbId) {
            var html = GetPage(ImdbMovieUrl.Replace("{ID}", imdbId));
            var entry = new ImdbMovieEntry();

            if(!string.IsNullOrEmpty(html)) {
                entry.ImdbId = imdbId;
                entry.ImdbHtml = html;

                var mTitleYear = Regex.Match(html, "<meta property=\"og:title\" content=\"([^(]+) \\(([0-9]+)");
                if (mTitleYear.Success) {
                    entry.Title = WebUtility.HtmlDecode(mTitleYear.Groups[1].Value);
                    entry.Year = DBFunc.ParseInt(mTitleYear.Groups[2].Value);
                }

                var mSummary = Regex.Match(html, "<h2>Storyline</h2>[\\r\\n]\\s*<p>([^<>]+)");
                if (mSummary.Success) {
                    entry.Summary = WebUtility.HtmlDecode(mSummary.Groups[1].Value);
                }

                var mPictureUrl = Regex.Match(html,
                                              "<a\\s*onclick=\"(?:[^\"]+\")\\s*href=\"(?:[^\"]+\")\\s*><img src=\"([^\"]+)\"[\\r\\n]*\\s*style=\"(?:[^\"]+\")[\\r\\n]*\\s*height=\"317\"");
                if (mPictureUrl.Success) {
                    var picdata = GetPage(mPictureUrl.Groups[1].Value);
                    entry.ThumbData = Encoding.Default.GetBytes(picdata);
                }

                var mGenres = Regex.Matches(html,
                                            "<a\\s*onclick=\"(?:[^\"]+\")\\s*href=\"/genre/([^\"]+)\"\\s* itemprop=\"genre\"");
                if (mGenres.Count > 0) {
                    var sh = DBHandler.GetHandler();
                    sh.Connect();
                    entry.Genre = mGenres.Cast<Match>().Select(mGenre => GenreQueries.GetGenre(WebUtility.HtmlDecode(mGenre.Groups[1].Value), sh)).Where(genre => genre.Id > 0).ToList();
                    sh.Close();
                }

                var mRating = Regex.Match(html, "<span itemprop=\"contentRating\">Rated ([^ ]+)");
                if(mRating.Success) {
                    entry.ParentalGuidance = EnumHelper.GetParentalGuidanceExt(mRating.Groups[1].Value);
                }

                var mLanguage = Regex.Match(html, "itemprop=\"inLanguage\"[\\r\\n]\\s*>([^<]+)");
                if(mLanguage.Success) {
                    entry.Language = WebUtility.HtmlDecode(mLanguage.Groups[1].Value);
                }

                var mLength = Regex.Match(html, "itemprop=\"duration\" datetime=\"(?:[^\"]+)\">([0-9]+)");
                if(mLength.Success) {
                    entry.Length = DBFunc.ParseInt(mLength.Groups[1].Value);
                }

                var mReleaseDate = Regex.Match(html, "itemprop=\"datePublished\" datetime=\"([0-9]+-[0-9]+-[0-9]+)");
                if(mReleaseDate.Success) {
                    entry.ReleaseDate = DBFunc.ParseDateTime(mReleaseDate.Groups[1].Value);
                }
            }

            return entry;
        }

        public static string GetPage(string url) {
            var pageContent = string.Empty;
            try {
                var uri = new Uri(url);

                var req = (HttpWebRequest) WebRequest.Create(uri);
                req.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate");
                req.Headers.Add(HttpRequestHeader.AcceptLanguage, "en-us;q=0.7,en;q=0.3");
                req.AllowAutoRedirect = true;
                ServicePointManager.Expect100Continue = false;

                var res = (HttpWebResponse) req.GetResponse();
                var resStream = res.GetResponseStream();

                if(resStream != null) {

                    if (res.ContentEncoding.ToLower().Contains("gzip")) {
                        resStream = new GZipStream(resStream, CompressionMode.Decompress);
                    }
                    else if (res.ContentEncoding.ToLower().Contains("deflate")) {
                        resStream = new DeflateStream(resStream, CompressionMode.Decompress);
                    }

                    var encoding = GetEncoding(res.Headers[HttpResponseHeader.ContentEncoding]);
                    var reader = new StreamReader(resStream, encoding);
                    pageContent = reader.ReadToEnd();

                    res.Close();
                    resStream.Close();
                }
            }
            catch (Exception ex) {
                Console.Write(ex);
            }
            return pageContent;
        }

        public static Encoding GetEncoding(string encoding) {
            var theEncoding = Encoding.Default;
            try {
                theEncoding = Encoding.GetEncoding(encoding);
            }catch{}
            return theEncoding;
        }
    }
}